#include <vcclr.h>

#include "helper.h"
#include "WebCoreWrapper.h"
#include "WebViewWrapper.h"

using namespace AwesomiumDotNet;

AwesomiumDotNet::WebCoreConfig::WebCoreConfig()
{
	_config = new Awesomium::WebCoreConfig();
}

Awesomium::WebCoreConfig AwesomiumDotNet::WebCoreConfig::getNative()
{
	return *_config;
}

void AwesomiumDotNet::WebCoreConfig::SetEnablePlugins(bool enablePlugins)
{
	_config->setEnablePlugins(enablePlugins);
}

void AwesomiumDotNet::WebCoreConfig::SetEnableJavaScript(bool enableJavaScript)
{
	_config->setEnableJavascript(enableJavaScript);
}

void AwesomiumDotNet::WebCoreConfig::SetUserDataPath(String^ userDataPath)
{
	if (userDataPath != nullptr)
	{
		pin_ptr<const wchar_t> wch = PtrToStringChars(userDataPath);
		_config->setUserDataPath(wch);
	}
	else
	{
		_config->setUserDataPath(L"");
	}
}

void AwesomiumDotNet::WebCoreConfig::SetPluginPath(String^ pluginPath)
{
	if (pluginPath != nullptr)
	{
		pin_ptr<const wchar_t> wch = PtrToStringChars(pluginPath);
		_config->setPluginPath(wch);
	}
	else
	{
		_config->setPluginPath(L"");
	}
}

void AwesomiumDotNet::WebCoreConfig::SetLogPath(String^ logPath)
{
	if (logPath != nullptr)
	{
		pin_ptr<const wchar_t> wch = PtrToStringChars(logPath);
		_config->setLogPath(wch);
	}
	else
	{
		_config->setLogPath(L"");
	}
}

void AwesomiumDotNet::WebCoreConfig::SetLogLevel(LogLevel logLevel)
{
	_config->setLogLevel((Awesomium::LogLevel)logLevel);
}

void AwesomiumDotNet::WebCoreConfig::SetUserAgentOverride(String^ userAgentOverride)
{
	if (userAgentOverride != nullptr)
	{
		char* userAgentOverrideTemp = MarshalString(userAgentOverride);
		_config->setUserAgentOverride(userAgentOverrideTemp);
		FreeUnmanagedString(userAgentOverrideTemp);
	}
	else
	{
		_config->setUserAgentOverride("");
	}
}

void AwesomiumDotNet::WebCoreConfig::SetProxyServer(String^ proxyServer)
{
	char* proxyServerTemp = MarshalString(proxyServer);
	_config->setProxyServer(proxyServerTemp);
	FreeUnmanagedString(proxyServerTemp);
}

void AwesomiumDotNet::WebCoreConfig::SetProxyConfigScript(String^ proxyConfigScript)
{
	char* proxyConfigScriptTemp = MarshalString(proxyConfigScript);
	_config->setProxyConfigScript(proxyConfigScriptTemp);
	FreeUnmanagedString(proxyConfigScriptTemp);
}

void AwesomiumDotNet::WebCoreConfig::SetSaveCacheAndCookies(bool saveCacheAndCookies)
{
	_config->setSaveCacheAndCookies(saveCacheAndCookies);
}

void AwesomiumDotNet::WebCoreConfig::SetMaxCacheSize(int maxCacheSize)
{
	_config->setMaxCacheSize(maxCacheSize);
}

void AwesomiumDotNet::WebCoreConfig::SetDisableSameOriginPolicy(bool disableSameOriginPolicy)
{
	_config->setDisableSameOriginPolicy(disableSameOriginPolicy);
}

void AwesomiumDotNet::WebCoreConfig::SetCustomCss(String^ customCss)
{
	char* customCssTemp = MarshalString(customCss);
	_config->setCustomCSS(customCssTemp);
	FreeUnmanagedString(customCssTemp);
}

void AwesomiumDotNet::WebCoreConfig::SetCustomCssFromFile(String^ customCssFilePath)
{
	char* customCssFilePathTemp = MarshalString(customCssFilePath);
	_config->setCustomCSSFromFile(customCssFilePathTemp);
	FreeUnmanagedString(customCssFilePathTemp);
}

bool AwesomiumDotNet::WebCore::ArePluginsEnabled::get()
{
	return webCore->arePluginsEnabled();
}

String^ AwesomiumDotNet::WebCore::BaseDirectory::get()
{
	return gcnew String(webCore->getBaseDirectory().c_str());
}

void AwesomiumDotNet::WebCore::BaseDirectory::set(String^ value)
{
	wchar_t* valueTemp = MarshalStringW(value);
	webCore->setBaseDirectory(valueTemp);
	FreeUnmanagedString(valueTemp);
}

Awesomium::WebCore* AwesomiumDotNet::WebCore::getCore()
{
	return webCore;
}

bool AwesomiumDotNet::WebCore::IsDisposed::get()
{
	return webCore == 0;
}

AwesomiumDotNet::WebCore::WebCore()
{
	if (webCore == 0)
	{
		webCore = new Awesomium::WebCore();
		webViewList = gcnew List<WebView^>();
	}
}

AwesomiumDotNet::WebCore::WebCore(WebCoreConfig^ config)
{
	if (webCore == 0)
	{
		webCore = new Awesomium::WebCore(config->getNative());
		webViewList = gcnew List<WebView^>();
	}
}

AwesomiumDotNet::WebCore::~WebCore()
{
	while (webViewList->Count > 0)
		delete webViewList[0];
	delete webCore;
	webCore = 0;
}

void AwesomiumDotNet::WebCore::ClearCache()
{
	webCore->clearCache();
}

void AwesomiumDotNet::WebCore::ClearCookies()
{
	webCore->clearCookies();
}

AwesomiumDotNet::WebView^ AwesomiumDotNet::WebCore::CreateWebView(int width, int height)
{
	WebView^ webView = gcnew WebView(this, width, height);
	webViewList->Add(webView);
	return webView;
}

bool AwesomiumDotNet::WebCore::SetCookie(String^ url, String^ cookieString, bool isHttpOnly, bool forceSessionCookie)
{
	char* urlTemp = MarshalString(url);
	char* cookieStringTemp = MarshalString(cookieString);
	
	bool ret = webCore->setCookie(urlTemp, cookieStringTemp, isHttpOnly, forceSessionCookie);
	
	FreeUnmanagedString(cookieStringTemp);
	FreeUnmanagedString(urlTemp);
	return ret;
}

bool AwesomiumDotNet::WebCore::SetCookie(String^ url, String^ cookieString, bool isHttpOnly)
{
	char* urlTemp = MarshalString(url);
	char* cookieStringTemp = MarshalString(cookieString);
	
	bool ret = webCore->setCookie(urlTemp, cookieStringTemp, isHttpOnly);
	
	FreeUnmanagedString(cookieStringTemp);
	FreeUnmanagedString(urlTemp);
	return ret;
}

bool AwesomiumDotNet::WebCore::SetCookie(String^ url, String^ cookieString)
{
	char* urlTemp = MarshalString(url);
	char* cookieStringTemp = MarshalString(cookieString);
	
	bool ret = webCore->setCookie(urlTemp, cookieStringTemp);
	
	FreeUnmanagedString(cookieStringTemp);
	FreeUnmanagedString(urlTemp);
	return ret;
}

String^ AwesomiumDotNet::WebCore::GetCookies(String^ url, bool excludeHTTPOnly)
{
	char* urlTemp = MarshalString(url);
	std::string ret = webCore->getCookies(urlTemp, excludeHTTPOnly);
	FreeUnmanagedString(urlTemp);
	return gcnew String(ret.c_str());
}

String^ AwesomiumDotNet::WebCore::GetCookies(String^ url)
{
	char* urlTemp = MarshalString(url);
	std::string ret = webCore->getCookies(urlTemp);
	FreeUnmanagedString(urlTemp);
	return gcnew String(ret.c_str());
}

void AwesomiumDotNet::WebCore::DeleteCookie(String^ url, String^ cookieName)
{
	char* urlTemp = MarshalString(url);
	char* cookieNameTemp = MarshalString(cookieName);

	webCore->deleteCookie(urlTemp, cookieNameTemp);

	FreeUnmanagedString(cookieNameTemp);
	FreeUnmanagedString(urlTemp);
}

void AwesomiumDotNet::WebCore::SetCustomResponsePage(int statusCode, String^ filePath)
{
	wchar_t* filePathTemp = MarshalStringW(filePath);
	webCore->setCustomResponsePage(statusCode, filePathTemp);
	FreeUnmanagedString(filePathTemp);
}

void AwesomiumDotNet::WebCore::Update()
{
	webCore->update();

	// WebViews that were marked to be destroyed were cleaned up during the update call,
	// so we clean up the managed wrappers here.
	int i = 0;
	while (i < webViewList->Count)
	{
		WebView^ view = webViewList[i];
		if (view->markedDestroyed)
			delete view;

		i++;
	}
}

void AwesomiumDotNet::WebCore::SetSuppressPrinterDialog(bool suppress)
{
	webCore->setSuppressPrinterDialog(suppress);
}
